#include <netinet/in.h>
#include <stdint.h>
#include <stdio.h>
#include <endian.h>
#include <string.h>

// 参考 "~/MyWorkspace/skynet_dir/skynet/lualib-src/lua-netpack.c" 文件,

static inline void
write_size(uint8_t *buffer, int len)
{
    buffer[0] = (len >> 8) & 0xff;
    buffer[1] = len & 0xff;
}

//
// __BIG_ENDIAN 和__LITTLE_ENDIAN  只要通过引入头文件 <endian.h> 便可以在编译时通过宏判断字节序了
// #if __BYTE_ORDER == __LITTLE_ENDIAN
// #elif __BYTE_ORDER == __BIG_ENDIAN
// #else
// #error "Unknown byte order"
// #endif
//

#if defined(__i386__) || defined(__amd64__)
#if __BYTE_ORDER == __LITTLE_ENDIAN
uint32_t my_ntohl(uint32_t netlong)
{
    return ((netlong & 0xff) << 24) | ((netlong & 0xff00) << 8) | ((netlong >> 8) & 0xff00) | ((netlong >> 24) & 0xff);
}

uint16_t my_ntohs(uint16_t netshort)
{
    return ((netshort & 0xff) << 8) | ((netshort >> 8) & 0xff);
}

uint32_t my_htonl(uint32_t hostlong)
{
    return ((hostlong & 0xff) << 24) | ((hostlong & 0xff00) << 8) | ((hostlong >> 8) & 0xff00) | ((hostlong >> 24) & 0xff);
}

uint16_t my_htons(uint16_t hostshort)
{
    return ((hostshort & 0xff) << 8) | ((hostshort >> 8) & 0xff);
}
#elif __BYTE_ORDER == __BIG_ENDIAN
uint32_t my_ntohl(uint32_t netlong)
{
    return netlong;
}
uint16_t my_ntohs(uint16_t netshort) { return netshort; }
uint32_t my_htonl(uint32_t hostlong) { return hostlong; }
uint16_t my_htons(uint16_t hostshort) { return hostshort; }
#else
#error "Unknown byte order"
#endif
#endif

int main()
{
    printf("%lu, %lu\n", sizeof(int), sizeof(size_t)); // 4, 8
    uint32_t nbytes = 4096;
    char buf[4] = {0};
    memcpy(buf, (void *)&nbytes, 4);
    printf("4096 = 0x%02x 0x%02x 0x%02x 0x%02x\n", buf[0], buf[1], buf[2], buf[3]); // 0x0, 0x10, 0x0 ,0x0
    printf("(4096 & 0x1000) = 0x%x\n", (4096 & 0x1000)); // (4096 & 0x1000) = 0x1000

    printf("sizeof(long) = %lu,   sizeof(long long)= %lu\n", sizeof(long), sizeof(long long));
    uint16_t big_short = htons(5);
    uint32_t big_long = htonl(5);
    uint16_t big_short1 = my_htons(5);
    uint32_t big_long1 = my_htonl(5);
    printf("%u %u %u %u\n", big_short, big_long, big_short1, big_long1);

    uint16_t big_endian = my_htons(5);
    uint16_t little_endian = my_ntohs(big_endian);
    printf("%d %d\n", big_endian, little_endian);
    return 0;
}